package es.udc.acs.consorcio.ui;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;

import es.udc.acs.consorcio.client.ControlClient;
import es.udc.acs.consorcio.mensaje.GestorMensaje;
import es.udc.acs.consorcio.server.CajeroServer;
import es.udc.acs.consorcio.server.ControlServer;
import es.udc.acs.consorcio.sesion.GestorSesion;
import es.udc.acs.consorcio.sesion.Sesion;
import es.udc.acs.database.Database;
import es.udc.acs.database.operations.DBConsorcioOperations;
import es.udc.acs.parser.ParserMensaje;
import es.udc.acs.udp.QuestionServer;
import es.udc.acs.udp.ServerUDP;
import es.udc.acs.utils.CodigosFAP;
import es.udc.acs.utils.GestorProperties;

public class MainConsorcio {

	private static boolean disponible = false;
	
	public static void main(String[] args) {
		QuestionServer cajeroServer  = new CajeroServer();
		QuestionServer controlServer = new ControlServer();
		String auxPort;
		int portCajeros;
		int portControl;
		
		Database db = Database.getInstancia();
		try {
			db.establecerConexion();
			
			modoInicializar();
			
			auxPort     = GestorProperties.devolverPropiedad(GestorProperties.PUERTOCAJEROS);
			portCajeros = Integer.parseInt(auxPort.substring(16, 20));
			
			auxPort     = GestorProperties.devolverPropiedad(GestorProperties.PUERTOBANCOS);
			portControl = Integer.parseInt(auxPort.substring(16, 20));
			
			new ServerUDP(portCajeros, cajeroServer).start();
			new ServerUDP(portControl, controlServer).start();
			
			System.out.println("Consorcio arrancado");
			
			menu();
			
		} catch (Exception e) {
			e.printStackTrace();
		}		

	}
	

	private static void menu() {
		
		BufferedReader br = 
				new BufferedReader(new InputStreamReader(System.in));
		
		while(true){
			String op = "";
			
			System.out.println("Seleccione operacion:");
			System.out.println("\t1.-Modo recuperacion.");
			System.out.println("\t2.-Modificar disponibilidad.");
			
		    try {
				op = (br.readLine());
				System.out.println("");
			} catch (IOException e) {
				System.out.println("Opcion no valida.");
				e.printStackTrace();
			}
			if (op.equals("1")){	
				modoRecuperacion();
			}else if (op.equals("2")){
				modoDisponible();
			}else 
				System.out.println("Opcion no valida.");
		}
	}
	
	
	private static void modoRecuperacion() {
		
		BufferedReader br = 
				new BufferedReader(new InputStreamReader(System.in));
		
		if (!GestorSesion.mostrarSesiones()) {
			return;
		}
		
		while(true){
			String op = "";
			
			System.out.println("Escriba la sesion que quiera cambiar a modo " 
					+"recuperacion");
		    try {
				op = (br.readLine());
			} catch (IOException e) {
				System.out.println("Opcion no valida.");
				e.printStackTrace();
			}
		    
		    System.out.println(op);
			if (op.length() != 8){	
				System.out.println("Tamaño no valido");
				continue;
			}
			
			Sesion sesion = GestorSesion.getSesion(op);
			if (sesion == null) {
				System.out.println("No existe sesion para ese banco");
				break;
			}
			
			if (!lanzarRecuperacion(sesion)) {
				System.out.println("No se ha podido realizar la recuperacion");
			}
			
			break;
		}
	}

	
	private static boolean lanzarRecuperacion(Sesion sesion) {
		
		if (sesion.obtenerEstado().equals("Recibiendo"))  {
			
			if(!ControlClient.startRecuperacion(sesion)){
				return false;
			}
			
			sesion.enRecuperacion();
			
			if(!ControlClient.finRecuperacion(sesion)){
				GestorProperties.getConsorcioLog().getLogger().
						log(Level.ALL, "<" + sesion.getBanco() 
								+ "> No se pudo salir de recuperacion ");
			}else {
				sesion.mostrarCanales();
				sesion.finRecuperacion();
			}
			
			return true;
		}
		return false;
	}

	private static void modoDisponible() {
		
		BufferedReader br = 
				new BufferedReader(new InputStreamReader(System.in));
		
		while(true){
			String op = "";
			
			System.out.println("Modo diponible: "+getDisponible());
			System.out.println("\t1.-Disponible.");
			System.out.println("\t2.-No disponible.");
		    try {
				op = (br.readLine());
			} catch (IOException e) {
				System.out.println("Opcion no valida.");
				e.printStackTrace();
			}
			if (op.equals("1")){				
				setDisponible(true);	
			} else if (op.equals("2")){				
				setDisponible(false);	
			} else 
				System.out.println("Opcion no valida.");
			break;
		}
	}
	
	
    private static void modoInicializar() {
    	
		BufferedReader br = 
				new BufferedReader(new InputStreamReader(System.in));
		
		String op = "";
		
		while(true){
			System.out.println("Inicio limpio del consorcio? (si/no)");
			
		    try {
				op = (br.readLine());
				System.out.println("");
			} catch (IOException e) {
				System.out.println("Opcion no valida.");
				e.printStackTrace();
			}
		    if (!op.equals("si") && !op.equals("no")){	
				System.out.println("Opcion no valida.");
			}else {
				if (op.equals("si")) {
					try {
						DBConsorcioOperations.borrarConsorcioDB();
					} catch (Exception e) {
						System.out.println("Error al borrar entradas antiguas");
						e.printStackTrace();
					}
				} else {
					GestorSesion.cargarSesiones();
					GestorMensaje.cargarMensajes();
				}	
				break;
			}
		}			
    }

	public static boolean getDisponible() {
		return disponible;
	}

	private static void setDisponible(boolean dis) {
		disponible = dis;
	}

}
